package icu.thatyear.main.satoken.service;

import cn.dev33.satoken.stp.StpInterface;
import jakarta.annotation.Resource;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Component;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;

/**
 * 自定义权限认证接口扩展，Sa-Token 将从此实现类获取每个账号拥有的权限码
 * 只要实现了SaToken的StpInterface接口，
 * 并且加了@Component被SpringBoot管理，框架就会自动帮我们进行执行业务逻辑
 *
 * @author huahua
 * @since 2024/8/23
 */
@Component
public class StpInterfaceImpl implements StpInterface {

    @Resource
    private JdbcTemplate jdbcTemplate;

    // 权限认证校验SaCheckPermission,SaCheckRole注解，必须具有指定权限才能进入该方法。
    // 可以标注在方法、类上（效果等同于标注在此类的所有方法上）

    /**
     * 根据登录id和登录类型获取用户权限列表，返回一个账号所拥有的 权限 码集合
     * <p>
     * 该方法通过查询数据库，获取指定用户所拥有的所有权限代码
     * 查询涉及3张自定义报表：role_user角色用户关联表、role_promission角色权限关联表、promisssion权限表
     * 查询条件为用户id，连接3个表获取当前用户所有角色权限信息，从而提取权限代码
     *
     * @param loginId   用户登录id
     * @param loginType 登录类型
     * @return 权限列表
     */
    @Override
    public List<String> getPermissionList(Object loginId, String loginType) {
        System.out.println("读取权限列表");
        List<String> list = new ArrayList<>();
        // 通过用户id查询此id对应的权限列表
        List<Map<String, Object>> maps = jdbcTemplate.queryForList("select distinct promission_code from role_users ru,role_promission rp,promission p" +
                " where ru.role_id = rp.role_id and rp.promission_id = p.promission_id and ru.user_id = ?", loginId);
        for (Map<String, Object> map : maps) {
            list.add(map.get("promission_code").toString());
        }
        return list;
    }

    /**
     * 根据登录id和登录类型获取用户权限列表，返回一个账号所拥有的 角色 码集合
     *
     * @param loginId   用户登录id
     * @param loginType 登录类型
     * @return 角色列表
     */
    @Override
    public List<String> getRoleList(Object loginId, String loginType) {
        List<String> list = new ArrayList<>();
        List<Map<String, Object>> maps = jdbcTemplate.queryForList("select distinct r.role_code from role_users ru,role r where ru.role_id = r.role_id and ru.user_id = ?", loginId);
        for (Map<String, Object> map : maps) {
            list.add(map.get("role_code").toString());
        }
        return list;
    }

}
